Skip to content

Feat/settings flow#238

Merged
LeonardoVieira1630 merged 34 commits into
devfrom
feat/settings_flow
Mar 30, 2026
Merged

Feat/settings flow#238
LeonardoVieira1630 merged 34 commits into
devfrom
feat/settings_flow

Conversation

@LeonardoVieira1630

@LeonardoVieira1630 LeonardoVieira1630 commented Mar 26, 2026

Copy link
Copy Markdown
Member

Summary

Add user notification preferences (settings) allowing users to choose which notification types they receive, and add support for offchain vote cast notifications. The settings flow is available via Telegram and Slack bots, backed by a new user_notification_preferences database table and API endpoints. The dispatcher now filters subscribers by triggerType so users only receive notifications they've opted into.

Changes

  • Notification Settings UI: Add /settings command and interactive settings flow for both Telegram (toggle grid) and Slack (checkbox list), built on a shared BaseSettingsService
  • Settings API & persistence: Add settings.controller, settings.handler, settings.service, and UserNotificationPreferences repository in subscription-server with GET and PUT endpoints
  • Database migration: Add user_notification_preferences table to store per-user trigger-type opt-in/out preferences
  • triggerType filtering: Extend getSubscribers, getDaoSubscribers, getWalletOwners, and batch methods across the dispatcher and subscription-client to propagate and filter by triggerType
  • Unique voting-reminder trigger IDs: Split voting reminder into distinct 30/60/90 trigger IDs for granular preference control
  • NOTIFICATION_TYPES constant: Add shared constant in the messages package mapping trigger IDs to user-facing labels
  • Offchain vote cast feature: Add offchain vote cast trigger, handler, message templates, and GraphQL query in anticapture-client
  • Onboarding update: Settings mention added to onboarding messages; learn_more_settings action now opens the settings flow
  • Tests: Add unit tests for settings service and preferences repository, integration tests for notification settings filtering and offchain vote cast trigger
  • Refactoring: Improve DAO confirm message, clean up and restructure existing tests to follow better patterns

LeonardoVieira1630 and others added 21 commits March 25, 2026 18:29
Adds IUserNotificationPreferencesRepository interface and UserNotificationPreference
entity to the interfaces file, then implements the repository with findByUser,
upsertMany (insert-or-update via onConflict merge), and filterActiveUsers (missing
row = enabled, only is_active=false rows are excluded). 13 unit tests cover all
methods and edge cases with 100% statement/branch coverage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements GET and POST /users/by-channel/:channel/:channelUserId/notification-preferences endpoints with Zod schema validation, handler, and controller. Wires SettingsService and UserNotificationPreferencesRepository into the App bootstrap. Adds @notification-system/messages as a workspace dependency to fix the missing module error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add optional triggerType parameter to getDaoSubscribers across the service,
handler, controller, and schema layers so callers can filter subscribers to
only those who have the given notification type enabled.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ration x3

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NewProposalTriggerHandler, NewOffchainProposalTriggerHandler, and
ProposalFinishedTriggerHandler now pass their respective triggerType
strings to getSubscribers, enabling per-user preference filtering.
Updated all affected test assertions accordingly, and fixed a
pre-existing test bug in offchain-vote-cast where buildExpectedMessage
was missing the address placeholder substitution.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Updated VoteConfirmationTriggerHandler, OffchainVoteCastTriggerHandler,
and VotingPowerTriggerHandler to pass triggerType to all getWalletOwnersBatch,
getSubscribers, and getDaoSubscribers calls, enabling per-notification-type
preference filtering for hybrid handlers. Updated test expectation to match.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ng + VotingReminder handlers

- Add optional `triggerType` param to `prepareBatchData` and forward it to `getWalletOwnersBatch` and `getDaoSubscribers`
- Add `triggerType` as 3rd parameter to `sendBatchNotifications` (between `daoId` and `eventIdGenerator`)
- NonVotingHandler passes `'non-voting'` as triggerType to `sendBatchNotifications`
- VotingReminderTriggerHandler accepts `triggerType` in `processReminderEvent` and passes `message.triggerId` from `handleMessage`
- Update test assertions to reflect new triggerType arguments

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add triggerType assertions to 4 handler test files (new-offchain-proposal, offchain-vote-cast, vote-confirmation, voting-power-changed) and create a NOTIFICATION_TYPES safety net test to ensure all dispatcher handler IDs have matching entries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The subscription-server App constructor now requires settingsController,
but the integration test setup was not passing it. Also added
user_notification_preferences to the database cleanup list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel

vercel Bot commented Mar 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flow-editor Ready Ready Preview, Comment Mar 30, 2026 2:47pm
notification-system-dashboard Ready Ready Preview, Comment Mar 30, 2026 2:47pm

Request Review

@LeonardoVieira1630 LeonardoVieira1630 changed the base branch from dev to feat/offchain-vote-cast-trigger March 26, 2026 13:10
LeonardoVieira1630 and others added 2 commits March 26, 2026 16:40
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread packages/messages/src/notification-types.ts Outdated
windowSize: number = DEFAULT_WINDOW_SIZE
) {
super(TRIGGER_ID_PREFIX, interval);
super(`${TRIGGER_ID_PREFIX}-${thresholdPercentage}`, interval);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the checkboxes, make sure that all the string is readable

Comment thread apps/dispatcher/src/services/triggers/base-trigger.service.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants